package movement

import (
	b "code.google.com/p/gochess/board"
	pos "code.google.com/p/gochess/position"
)

// using the approach of Tomasz Michniewski, found at
// http://chessprogramming.wikispaces.com/Simplified+evaluation+function
// tables are for white, rank 1 is bottom row
var pieceSquareTable64 [pos.BiggestPieceType + 1][64]int32

var pieceSquareTable [pos.BiggestPiece + 1][b.H8 + 1]int32

func init() {
	pieceSquareTable64[pos.Pawn] = [64]int32{
		00, 00, 00, 00, 00, 00, 00, 00,
		50, 50, 50, 50, 50, 50, 50, 50,
		10, 10, 20, 30, 30, 20, 10, 10,
		05, 05, 10, 25, 25, 10, 05, 05,
		00, 00, 00, 20, 20, 00, 00, 00,
		05, -05, -10, 00, 00, -10, -05, 05,
		05, 10, 10, -20, -20, 10, 10, 05,
		00, 00, 00, 00, 00, 00, 00, 00,
	}

	pieceSquareTable64[pos.Knight] = [64]int32{
		-50, -40, -30, -30, -30, -30, -40, -50,
		-40, -20, 00, 00, 00, 00, -20, -40,
		-30, 00, 10, 15, 15, 10, 00, -30,
		-30, 05, 15, 20, 20, 15, 05, -30,
		-30, 00, 15, 20, 20, 15, 00, -30,
		-30, 05, 10, 15, 15, 10, 05, -30,
		-40, -20, 00, 05, 05, 00, -20, -40,
		-50, -40, -30, -30, -30, -30, -40, -50,
	}

	pieceSquareTable64[pos.Bishop] = [64]int32{
		-20, -10, -10, -10, -10, -10, -10, -20,
		-10, 00, 00, 00, 00, 00, 00, -10,
		-10, 00, 05, 10, 10, 05, 00, -10,
		-10, 05, 05, 10, 10, 05, 05, -10,
		-10, 00, 10, 10, 10, 10, 00, -10,
		-10, 10, 10, 10, 10, 10, 10, -10,
		-10, 05, 00, 00, 00, 00, 05, -10,
		-20, -10, -10, -10, -10, -10, -10, -20,
	}

	pieceSquareTable64[pos.Rook] = [64]int32{
		00, 00, 00, 00, 00, 00, 00, 00,
		05, 10, 10, 10, 10, 10, 10, 05,
		-05, 00, 00, 00, 00, 00, 00, -05,
		-05, 00, 00, 00, 00, 00, 00, -05,
		-05, 00, 00, 00, 00, 00, 00, -05,
		-05, 00, 00, 00, 00, 00, 00, -05,
		-05, 00, 00, 00, 00, 00, 00, -05,
		00, 00, 00, 05, 05, 00, 00, 00,
	}

	pieceSquareTable64[pos.Queen] = [64]int32{
		-20, -10, -10, -05, -05, -10, -10, -20,
		-10, 00, 00, 00, 00, 00, 00, -10,
		-10, 00, 05, 05, 05, 05, 00, -10,
		-05, 00, 05, 05, 05, 05, 00, -05,
		00, 00, 05, 05, 05, 05, 00, -05,
		-10, 05, 05, 05, 05, 05, 00, -10,
		-10, 00, 05, 00, 00, 00, 00, -10,
		-20, -10, -10, -05, -05, -10, -10, -20,
	}

	// king middle game
	pieceSquareTable64[pos.King] = [64]int32{
		-30, -40, -40, -50, -50, -40, -40, -30,
		-30, -40, -40, -50, -50, -40, -40, -30,
		-30, -40, -40, -50, -50, -40, -40, -30,
		-30, -40, -40, -50, -50, -40, -40, -30,
		-20, -30, -30, -40, -40, -30, -30, -20,
		-10, -20, -20, -20, -20, -20, -20, -10,
		20, 20, 0, 0, 0, 0, 20, 20,
		20, 30, 10, 0, 0, 10, 30, 20,
	}

	// todo: king (distinction between mid game and end game required)
	for pieceType := pos.Pawn; pieceType <= pos.King; pieceType++ {
		for index := range pieceSquareTable64[pieceType] {
			for _, color := range [...]pos.Color{pos.White, pos.Black} {
				square := getTableIndex(color, index)
				pieceSquareTable[pos.NewPiece(color, pieceType)][square] =
					pieceSquareTable64[pieceType][index]
			}
		}
	}
}

func getTableIndex(color pos.Color, index int) b.Square {

	var rank, file int

	switch color {
	case pos.White:
		file = index%8 + 1
		rank = (63-index)/8 + 1
	case pos.Black:
		file = 8 - index%8
		rank = index/8 + 1
	default:
		panic("unknown Color")
	}
	return b.GetSquare(b.File(file-1)+b.A, b.Rank(rank-1)+b.Rank1)
}

func PositionBonus(piece pos.Piece, location b.Square) int32 {
	Stats.PositionBonus++
	return pieceSquareTable[piece][location]
}
